package com.example.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.example.mapper.UserMapper;
import com.example.pojo.Result;
import com.example.pojo.User;
import com.example.service.UserService;
import com.example.utils.*;
import io.jsonwebtoken.Claims;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.example.utils.RedisConstants.LOGIN_CODE_KEY;
import static com.example.utils.RedisConstants.LOGIN_CODE_TTL;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;


    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public User findByUsername(String username) {
        User user = userMapper.findByUsername(username);
        return user;
    }

    @Override
    public void register(String username, String password) {
        //加密
        String md5String =  Md5Util.getMD5String(password);
        //添加
        userMapper.add(username,md5String);
    }

    @Override
    public void update(User user) {
        Claims claims = ThreadLocalUtil.get();
        Integer id = (Integer) claims.get("id");
        user.setId(id);
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
    }

    @Override
    public void updateAvatar(String avatarUrl) {
        Claims claims = ThreadLocalUtil.get();
        Integer id = (Integer) claims.get("id");
        userMapper.updateAvatar(avatarUrl,id);
    }
   //更新密码
    @Override
    public void updatePwd(String newPwd) {
        Claims claims = ThreadLocalUtil.get();
        Integer id = (Integer) claims.get("id");
        userMapper.updatePwd(Md5Util.getMD5String(newPwd),id);
    }

    @Override
    public Result sendCode(String phone) {
        //1.校验手机号
        log.info("收到手机号：{} 验证码请求",phone);
        if(RegexUtils.isPhoneInvalid(phone)){
            //2.如果不符合返回错误信息
            return Result.error("手机号格式错误");
        }
        //3.生成验证码
        String code = RandomUtil.randomNumbers(6);

        //利用阿里云SMS服务发送短信验证码到用户手机
         //SMSUtil.sendMessage("阿里云短信测试", "SMS_154950909", phone, code);

        //利用阿里云SMS服务发送短信验证码到用户手机
        SMSUtil.sendMessage("趣享岛", "SMS_487255625", phone, code);

        //4.保存验证码到Redis 10分钟
        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY+phone,code,LOGIN_CODE_TTL, TimeUnit.MINUTES);

        //5.发送验证码
        log.info("发送验证码成功，验证码：{}",code);
        return Result.success(code);
    }

    @Override
    public User findByPhone(String phone) {
        User user = userMapper.findByPhone(phone);
        return user;
    }

    @Override
    public String loginByPhone(String phone, String code) {
        //1.校验手机号
        log.info("收到手机号：{} 验证码请求",phone);
        if(RegexUtils.isPhoneInvalid(phone)){
            //2.如果不符合返回错误信息
            return "手机号格式错误";
        }
        Long expire = stringRedisTemplate.getExpire(LOGIN_CODE_KEY+phone, TimeUnit.MINUTES);
        log.info("验证码剩余有效期：{}秒", expire);

//        从Redis中获取验证码并且校验
        String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY+phone);
        log.info("验证码：{}", cacheCode);
        if(cacheCode == null || !cacheCode.equals(code)){
            //3.不一致，返回错误信息
            return "验证码错误";
        }
        //4.一致，根据手机号查询用户
        User user = userMapper.findByPhone(phone);
        //5.判断用户是否存在
        if(user == null){
            //6.不存在，创建新用户
            user = new User();
            user.setPhone(phone);
            user.setNickname("user_"+RandomUtil.randomNumbers(4));
            //将手机号码转换类型变成字符串作为用户名
            user.setUsername(phone);
            //设置初始密码123456
            user.setPassword(Md5Util.getMD5String("123456"));
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            userMapper.addNew(user);//新增用户
            log.info(String.valueOf(user.getId())); // 自动注入自增后的ID
            //7.存在，保存用户信息到Redis
            Map<String, Object> Claims = new HashMap<>();
            Claims.put("id",user.getId());
            Claims.put("username",user.getUsername());
//            下发令牌
            String token = JwtUtils.generateJwt(Claims);//jwt包含了当前登录的用户信息
            return token;
        }
        //7.存在，保存用户信息到Redis
        Map<String, Object> Claims = new HashMap<>();
        Claims.put("id",user.getId());
        Claims.put("username",user.getUsername());
        String token = JwtUtils.generateJwt(Claims);//jwt包含了当前登录的用户信息
        return token;
    }

    @Override
    public List<User> list() {
        List<User> list = userMapper.list();
        return list;
    }

    @Override
    public void disable(Integer id) {
        userMapper.disable(id);
    }

    @Override
    public void delete(Integer id) {
        userMapper.delete(id);
    }

    @Override
    public List<User> search(String username, Integer id, String phone, Integer role) {
            return userMapper.search(username,id,phone,role);
    }

    @Override
    public User findById(Integer id) {
        User user = userMapper.findById(id);
        return user;
    }


}
